/*
 * Copyright (c) 2020 Nanjing Xiaoxiongpai Intelligent Technology Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "ohos_init.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <math.h>
#include "cmsis_os2.h"
#include "rice.h"
#include "wifiiot_errno.h"
#include "wifiiot_pwm.h"
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"
#include "wifiiot_i2c.h"
#include "wifiiot_i2c_ex.h"
#include "hi_time.h"

#define THE_CYCLES_OF_PWM_CONTROL 20000

/***************************************************************
* 函数名称: E53_SC1_IO_Init
* 说    明: E53_SC1_GPIO初始化
* 参    数: 无
* 返 回 值: 无
***************************************************************/
static void rice_IO_Init(void)
{

    GpioInit();
    
    //管脚复用

    //放米舵机
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_2, WIFI_IOT_IO_FUNC_GPIO_2_GPIO);
    //空洗直流电机①
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_3, WIFI_IOT_IO_FUNC_GPIO_3_GPIO);
    //空洗直流电机②
    
    //输送舵机
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_5, WIFI_IOT_IO_FUNC_GPIO_5_GPIO);
    //水泵直流电机
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_6, WIFI_IOT_IO_FUNC_GPIO_6_GPIO);
    //开盖舵机
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_7, WIFI_IOT_IO_FUNC_GPIO_7_GPIO);
    //气压舵机
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_8, WIFI_IOT_IO_FUNC_GPIO_8_GPIO);
    //煮饭舵机
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_9, WIFI_IOT_IO_FUNC_GPIO_9_GPIO);
    //总电源开关
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_14,WIFI_IOT_IO_FUNC_GPIO_14_GPIO);


    //设置管脚均为输出方向
    GpioSetDir(WIFI_IOT_GPIO_IDX_2,  WIFI_IOT_GPIO_DIR_OUT);
    GpioSetDir(WIFI_IOT_GPIO_IDX_3,  WIFI_IOT_GPIO_DIR_OUT);
    GpioSetDir(WIFI_IOT_GPIO_IDX_5,  WIFI_IOT_GPIO_DIR_OUT);
    GpioSetDir(WIFI_IOT_GPIO_IDX_6,  WIFI_IOT_GPIO_DIR_OUT);
    GpioSetDir(WIFI_IOT_GPIO_IDX_7,  WIFI_IOT_GPIO_DIR_OUT);
    GpioSetDir(WIFI_IOT_GPIO_IDX_8,  WIFI_IOT_GPIO_DIR_OUT);
    GpioSetDir(WIFI_IOT_GPIO_IDX_9,  WIFI_IOT_GPIO_DIR_OUT);
    GpioSetDir(WIFI_IOT_GPIO_IDX_14, WIFI_IOT_GPIO_DIR_OUT);

    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_0, WIFI_IOT_IO_FUNC_GPIO_0_I2C1_SDA);   // GPIO_0复用为I2C1_SDA
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_1, WIFI_IOT_IO_FUNC_GPIO_1_I2C1_SCL);   // GPIO_1复用为I2C1_SCL
    I2cInit(WIFI_IOT_I2C_IDX_1, 400000); /* baudrate: 400kbps */
    I2cSetBaudrate(WIFI_IOT_I2C_IDX_1, 400000);  
       
}

/**************************************************************
 * 函数名称: Init_rice
 * 说    明：初始化各路电机
 * 参    数: 无
 * 返 回 值: 无
***************************************************************/

void Init_rice(void)
{
    //空洗直流电机初始为0
    //水泵直流电机
    /* GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_6, 0);
    GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_3, 0);
    hi_udelay(10000);*/

    //放米舵机(MG90)初始到0°
    for (int  i = 1; i <=20 ; i++) 
    {
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_2, 1);
        hi_udelay(500);
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_2, 0);
        hi_udelay(THE_CYCLES_OF_PWM_CONTROL-500);       
    }
    hi_udelay(10000);

    //气压舵机(MG90)状态为90度(关闭状态)：这里假设已经完成
    for (int  i = 1; i <=20 ; i++) 
    {
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 1);
        hi_udelay(1500);
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 0);
        hi_udelay(THE_CYCLES_OF_PWM_CONTROL-1500);       
    }
    hi_udelay(10000);

}

/***************************************************************
* 函数名称: start_rice
* 说    明: 写命令初始化BH1750
* 参    数: 无
* 返 回 值: 无
***************************************************************/
void start_rice(void)
{
    //气压舵机(MG90)状态为90度:打开盖扣
    for (int  i = 1; i <=20 ; i++) 
    {
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 1);
        hi_udelay(1500);
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 0);
        hi_udelay(THE_CYCLES_OF_PWM_CONTROL-1500);       
    }
    hi_udelay(10000);
    

    //开盖舵机(MG955)旋转开锅
    int a =0;
    while(a<4)
    {
    for (int  i = 1; i <=20 ; i++) 
    {
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_7, 1);
        hi_udelay(1000);
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_7, 0);
        hi_udelay(THE_CYCLES_OF_PWM_CONTROL-1000);       
    }
    a++;
    }
    hi_udelay(10000);
    

    //输送舵机(MG955)转动出仓
    for (int  i = 1; i <=20; i++) 
    {
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_5, 1);
        hi_udelay(2000);
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_5, 0);
        hi_udelay(THE_CYCLES_OF_PWM_CONTROL-2000);       
    }
    hi_udelay(10000);

    //水泵直流电机启动
    GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_6, 1);
    hi_udelay(5000000);
    GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_6, 0);
    hi_udelay(5000000);

    //空洗直流电机初始为1
    GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_3, 1);
    hi_udelay(10000000);
    
    //放米舵机(MG90)转到90°：打开仓门
    for (int  i = 1; i <=20 ; i++) 
    {
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_2, 1);
        hi_udelay(1500);
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_2, 0);
        hi_udelay(THE_CYCLES_OF_PWM_CONTROL-1500);       
    }
    hi_udelay(10000);

    osDelay(500);

    //放米舵机(MG90)转到0°:关闭仓门
    for (int  i = 1; i <=20 ; i++) 
    {
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_2, 1);
        hi_udelay(500);
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_2, 0);
        hi_udelay(THE_CYCLES_OF_PWM_CONTROL-500);       
    }
    hi_udelay(10000);

    //空洗直流电机初始为0
    GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_3, 0);
    hi_udelay(10000000);

    

    //开盖舵机(MG955)旋转关锅
    int c =0;
    while(c<2)
    {
    for (int  i = 1; i <=20 ; i++) 
    {
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_7, 1);
        hi_udelay(2000);
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_7, 0);
        hi_udelay(THE_CYCLES_OF_PWM_CONTROL-2000);       
    }
    c++;
    }
    hi_udelay(10000);

    //气压舵机(MG90)状态为90度:关闭盖扣
    for (int  i = 1; i <=20 ; i++) 
    {
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 1);
        hi_udelay(500);
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 0);
        hi_udelay(THE_CYCLES_OF_PWM_CONTROL-500);       
    }
    hi_udelay(10000);

    //煮饭舵机(MG995)转动(按下按钮)
    int j = 0;
    while(j<2)
    {
        for (int  i = 1; i <=20 ; i++) 
        {
            GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_9, 1);
            hi_udelay(1000);
            GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_9, 0);
            hi_udelay(THE_CYCLES_OF_PWM_CONTROL-1000);       
        }
        hi_udelay(10000);
        j++;
    }

    //煮饭舵机(MG995)转回(松开按钮)
    int b = 0;
    while(b<1)
    {
        for (int  i = 1; i <=20 ; i++) 
        {
            GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_9, 1);
            hi_udelay(2000);
            GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_9, 0);
            hi_udelay(THE_CYCLES_OF_PWM_CONTROL-2000);       
        }
        hi_udelay(10000);
        b++;
    }

}
/***************************************************************
* 函数名称: stop_rice
* 说    明: 关闭电源供电
* 参    数: 无
* 返 回 值: 无
***************************************************************/
void stop_rice(void)
{
    int d=1;
    d = ~d;
    GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_14, d);
}
/***************************************************************
* 函数名称: Init_BH1750
* 说    明: 写命令初始化BH1750
* 参    数: 无
* 返 回 值: 无
***************************************************************/
void Init_BH1750(void)
{
    WifiIotI2cData bh1750_i2c_data = { 0 };
    uint8_t send_data[1] = { 0x01 };
    bh1750_i2c_data.sendBuf = send_data;
    bh1750_i2c_data.sendLen = 1;
	I2cWrite(WIFI_IOT_I2C_IDX_1,(BH1750_Addr<<1)|0x00,&bh1750_i2c_data); 
}

/***************************************************************
* 函数名称: Start_BH1750
* 说    明: 启动BH1750
* 参    数: 无
* 返 回 值: 无
***************************************************************/
void Start_BH1750(void)
{
    WifiIotI2cData bh1750_i2c_data = { 0 };
    uint8_t send_data[1] = { 0x10 };
    bh1750_i2c_data.sendBuf = send_data;
    bh1750_i2c_data.sendLen = 1;
	I2cWrite(WIFI_IOT_I2C_IDX_1,(BH1750_Addr<<1)|0x00,&bh1750_i2c_data); 
}
/***************************************************************
* 函数名称: E53_SC1_Init
* 说    明: 初始化E53_SC1
* 参    数: 无
* 返 回 值: 无
***************************************************************/
void E53_SC1_Init(void)
{
	rice_IO_Init();
	Init_BH1750();
}
/***************************************************************
* 函数名称: E53_SC1_Read_Data
* 说    明: 测量光照强度
* 参    数: 无
* 返 回 值: 光照强度
***************************************************************/
float E53_SC1_Read_Data(void)
{
	int result;
    Start_BH1750(); // 启动传感器采集数据
	usleep(180000);
    WifiIotI2cData bh1750_i2c_data = { 0 };
    uint8_t recv_data[2] = { 0 };
    bh1750_i2c_data.receiveBuf = recv_data;
    bh1750_i2c_data.receiveLen = 2;
	I2cRead(WIFI_IOT_I2C_IDX_1, (BH1750_Addr<<1)|0x01,&bh1750_i2c_data);   // 读取传感器数据
	result = (recv_data[0]<<8) + recv_data[1];  //合成数据，即光照数据	
	return (float)(result/1.2);    
}
/***************************************************************
* 函数名称: Light_StatusSet
* 说    明: 灯状态设置
* 参    数: status,ENUM枚举的数据
*									OFF,关灯
*									ON,开灯
* 返 回 值: 无
***************************************************************/
void Rice_StatusSet(Rice_Status_ENUM status)
{
	if(status == ON)
        start_rice();

    if(status == OFF)
        Init_rice();
}